(译) 几分钟学习一门编程语言之Python篇 (最新版)

几分钟学习一门编程语言之Python篇 (最新版)

翻译自 Learn X in Y Minutes: Where X = Python Learn X in Y Minutes: Where X = Python

Python由Guido Van Rossum发明于90年代初期,是当今最流行的编程语言之一,我深深被它清晰简洁的语法所折服并从此爱上了它。Python的代码之简洁,几乎就是可执行的伪代码。

若能提供给我们反馈,将非常欢迎!你可以通过推特@louiedinh或邮箱louiedinh AT gmail来联系我。

请注意:本文是专门针对Python 2.7的,但应该同样也适用于Python 2.x的。至于 Python 3.x,请阅读我们最新的指南 Learn X in Y Minutes: Where X = Python 3

# 单行注释以"#"字符开头

""" 我们可以使用三个双引号(")或单引号(')来表示多行字符串,这种方法常用来来写多行注释。
"""

####################################################
## 1. 基本数据类型和操作符
####################################################

# 数字
3  # => 3

# 数学运算跟你想象中的并没有啥不同
1 + 1  # => 2
8 - 1  # => 7
10 * 2  # => 20
35 / 5  # => 7

# 除法跟想象中略有不同,它的结果会自动向下取整
5 / 2  # => 2

# 要想得到我们期望的除法,我们首先需要学习浮点数`floats`
2.0     # This is a float
11.0 / 4.0  # => 2.75 啊哈...貌似结果好很多了

# 用双斜杠"//"做整型数除法,正负数都适用,结果会向下取整
5 // 3     # => 1
5.0 // 3.0 # => 1.0 # 对浮点数同样适用
-5 // 3  # => -2
-5.0 // 3.0 # => -2.0

# 取模运算
7 % 3 # => 1

# 指数(x的y次方)
2**4 # => 16

# 使用括号来增强计算的优先顺序
(1 + 3) * 2  # => 8

# 布尔运算 
# 注意 "and" 和 "or"大小写敏感
True and False #=> False
False or True #=> True

# 注意ints型跟布尔型的混用
0 and 2 #=> 0
-5 or 0 #=> -5
0 == False #=> True
2 == True #=> False
1 == True #=> True

# 用not来否定
not True  # => False
not False  # => True

# 表示相等用"=="
1 == 1  # => True
2 == 1  # => False

# 表示不等用"!="
1 != 1  # => False
2 != 1  # => True

# 更多比较操作
1 < 10  # => True
1 > 10  # => False
2 <= 2  # => True
2 >= 2  # => True

# 比较可以是级联的!
1 < 2 < 3  # => True
2 < 3 < 2  # => False

# 创建字符串用双引号“或者单引号'都行
"This is a string."
'This is also a string.'

# 字符串也可以相加!
"Hello " + "world!"  # => "Hello world!"

# ... 又或者相乘
"Hello" * 3  # => "HelloHelloHello"

# 字符串可以被认为是一系列字符组成的列表(list)
"This is a string"[0]  # => 'T'

# 百分号 % 用来格式化输出字符串
"%s can be %s" % ("strings", "interpolated")

# 还有一种新的方式来格式化输出字符串
# 我们推荐用这种方式
"{0} can be {1}".format("strings", "formatted")
# 如果你不喜欢用数字,也可以使用关键字参数
"{name} wants to eat {food}".format(name="Bob", food="lasagna")

# None也是一个对象
None  # => None

# 千万不要使用"=="来对一个对象和None作比较
# 正确的方法是用 "is"
"etc" is None  # => False
None is None  # => True

# 'is' 操作符用来比较俩对象的标识符(译者注:即内存地址)
# 它对于普通的数值比较不管用
# 但在处理对象比较时则很有用

# None, 0, 还有空字符串/列表在布尔运算中值都为False 
# 除此之外的其他值的布尔运算结果都是True
bool(0)  # => False
bool("")  # => False


####################################################
## 2. 变量和集合
####################################################

# 在所有2.x版本中,Python有一个print语句,但在Python 3里面被移除了
print "I'm Python. Nice to meet you!"
# Python还有一个print函数,只在python 2.7和python 3中有 
# 但是对于Python 2.7,你需要添加import(去掉前面的注释):
# from __future__ import print_function
print("I'm also Python! ")

# 给变量赋值前,无需事先声明
some_var = 5    # 变量的命名规范是用小写字母加下划线( lower_case_with_underscores)
some_var  # => 5

# 试图访问没有赋值的变量会抛出异常
# 参考”流程控制“部分来学习更多关于异常处理
some_other_var  # 会抛出一个NameError异常

# if可以作为表达式使用
"yahoo!" if 3 > 2 else 2  # => "yahoo!"

# 列表(Lists)用于存储一个序列(sequences)
li = []
# 你可以从一个预先填充好的列表开始
other_li = [4, 5, 6]

# 用append方法往列表末尾添加元素
li.append(1)    # li is now [1]
li.append(2)    # li is now [1, 2]
li.append(4)    # li is now [1, 2, 4]
li.append(3)    # li is now [1, 2, 4, 3]
# 用pop方法将元素从列表末尾删除
li.pop()        # => 返回3,li现在为[1, 2, 4]
# 让我们加回去
li.append(3)    # li现在又变回了[1, 2, 4, 3]

# 像访问任何数组一样访问列表的元素
li[0]  # => 1
# 用等号"="给已经初始化过的列表元素赋新值
li[0] = 42
li[0]  # => 42
li[0] = 1  # 注意:将li[0]的值赋值为原先的值
# 访问列表的最后一个元素的方法
li[-1]  # => 3

# 访问列表界外的元素会抛出一个IndexError异常
li[4]  # 抛出 IndexError

# 你可以使用切片语法来查看列表的一个区间
# (这个范围相当于数学中的左闭右开区间)
li[1:3]  # => [2, 4]
# 省略开头
li[2:]  # => [4, 3]
# 省略结尾
li[:3]  # => [1, 2, 4]
# 隔个选择
li[::2]   # =>[1, 4]
# 将列表反转
li[::-1]   # => [3, 4, 2, 1]
# 用下面的任意组合来完成高级的切片
# li[start:end:step]

# 用"del"从列表中删除任意元素
del li[2]   # li现在是[1, 2, 3]

# 列表可以相加
li + other_li   # => [1, 2, 3, 4, 5, 6]
# 注意: li和other_li的元素值并没有被改变

# 用"extend()"方法扩展(级联)列表
li.extend(other_li)   # 现在li是[1, 2, 3, 4, 5, 6]

# 查看列表中是否存在元素用"in"
1 in li   # => True

# 用"len()"检查列表长度
len(li)   # => 6


# 元祖(Tuples)和列表(lists)类似,只是它们"不可变"
tup = (1, 2, 3)
tup[0]   # => 1
tup[0] = 3  # 抛TypeError异常

# 你可以对元祖操作那些你操作列表的方法
len(tup)   # => 3
tup + (4, 5, 6)   # => (1, 2, 3, 4, 5, 6)
tup[:2]   # => (1, 2)
2 in tup   # => True

# 你可以将元祖(或者列表)元素分解后赋给几个变量
a, b, c = (1, 2, 3)     # a现在是1, b现在是2, c现在是3
# 如果你省略了括号,则元祖会被自动创建
d, e, f = 4, 5, 6
# 现在来瞧瞧交换两个值是多么容易N
e, d = d, e     # d现在是5,e现在是 4


# 字典存储映射表
empty_dict = {}
# 这里是一个预先填充的字典
filled_dict = {"one": 1, "two": 2, "three": 3}

# 用[]符号查找字典值
filled_dict["one"]   # => 1

# 用"keys()"方法得到所有的key值
filled_dict.keys()   # => ["three", "two", "one"]
# 注意 - 字典key的顺序不保证
# 你的结果可能跟这里显示的不完全一致

# 用"values()"方法获取列表的所有值
filled_dict.values()   # => [3, 2, 1]
# 注意 - 这里也有上面说的顺序的问题

# 用“in”来查找字典里是否含有某个key值
"one" in filled_dict   # => True
1 in filled_dict   # => False

# 试图查找不存在的key会抛出一个KeyError异常
filled_dict["four"]   # KeyError异常

# 使用"get()"方法来避免KeyError异常
filled_dict.get("one")   # => 1
filled_dict.get("four")   # => None
# 如果值不存在,get还方法支持传入一个默认参数
filled_dict.get("one", 4)   # => 1
filled_dict.get("four", 4)   # => 4
# 注意filled_dict.get("four")还是 => 4
# (get并没有为字典设置新值)

# 为字典的key设置值得语法跟列表类似
filled_dict["four"] = 4  # now, filled_dict["four"] => 4

# "setdefault()" 只在给定的key不存在时才往字典里插入值
filled_dict.setdefault("five", 5)  # filled_dict["five"]的值现在被置为5
filled_dict.setdefault("five", 6)  # filled_dict["five"]的值仍然是5


# 集合(Sets)存储的是...呃,集合!(类似列表但是不能包含重复的元素)
empty_set = set()
# 用一堆值来初始化一个"set()"
some_set = set([1, 2, 2, 3, 4])   # some_set现在是set([1, 2, 3, 4])

# 即使有时候看起来像是被排序过的,集合并不保证它元素的顺序
another_set = set([4, 3, 2, 2, 1])  # another_set现在是set([1, 2, 3, 4])

# 从Python 2.7开始, 可以用{}来声明一个集合
filled_set = {1, 2, 2, 3, 4}   # => {1, 2, 3, 4}

# 向集合中添加更多元素
filled_set.add(5)   # filled_set现在是{1, 2, 3, 4, 5}

# 交集运算用:&
other_set = {3, 4, 5, 6}
filled_set & other_set   # => {3, 4, 5}

# 并集运算用:|
filled_set | other_set   # => {1, 2, 3, 4, 5, 6}

# 差集运算用:-
{1, 2, 3, 4} - {2, 3, 5}   # => {1, 4}

# 检查元素在集合中存在与否用:in
2 in filled_set   # => True
10 in filled_set   # => False


####################################################
## 3. 流程控制
####################################################

# 我们先生成一个变量
some_var = 5

# 这是一个if语句,python中对齐是非常重要的!
# 输出 "some_var is smaller than 10"
if some_var > 10:
    print("some_var is totally bigger than 10.")
elif some_var < 10:    # 这里的elif从句是可选的
    print("some_var is smaller than 10.")
else:           # 这也是可选的
    print("some_var is indeed 10.")


"""
For语句用来对列表进行循环迭代 
输出:
    dog is a mammal
    cat is a mammal
    mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
    # You can use % to interpolate formatted strings
    print("%s is a mammal" % animal)

"""
"range(number)" 返回一从0到number(不包含)的一列数
输出:
    0
    1
    2
    3
"""
for i in range(4):
    print(i)

"""
While循环会一直执行,直到条件不再满足 
输出:
    0
    1
    2
    3
"""
x = 0
while x < 4:
    print(x)
    x += 1  # Shorthand for x = x + 1

# 用try/except语块来处理异常

# 适用于Python 2.6或更高版本:
try:
    # 用"raise"抛出一个异常
    raise IndexError("This is an index error")
except IndexError as e:
    pass    # Pass只是一个啥也不干的空操作,通常你会在这里写些恢复操作的代码 
except (TypeError, NameError):
    pass    # 如果需要,可以同时处理多个异常
else:   # 对于try/except语块是可选的,必须跟在所有except语块后面
    print "All good!"   # 只在try当中的代码没有抛出任何异常时执行

####################################################
## 4. 函数
####################################################

# 用"def"创建新的函数
def add(x, y):
    print("x is %s and y is %s" % (x, y))
    return x + y    # 用return语句返回值

# 调用带参数的函数
add(5, 6)   # =>输出"x is 5 and y is 6" 并返回结果11

# 调用函数的另一种方式:利用关键字
add(y=6, x=5)   # 关键字参数的顺序是任意的

# 你可以定义位置参数(positional args)个数可变的函数
# 这些位置参数将会被解释成一个元组,如果你不适用*号的话
def varargs(*args):
    return args

varargs(1, 2, 3)   # => (1, 2, 3)


# 你可以定义关键字参数(keyword args)可变的函数
# 同样,这些关键字参数将会被解释成一个map,如果你不使用**号的话
def keyword_args(**kwargs):
    return kwargs

# 让我们调用下,看看发生了什么
keyword_args(big="foot", loch="ness")   # => {"big": "foot", "loch": "ness"}


# 如果愿意,你可以同时使用可变位置参数和可变关键字参数
def all_the_args(*args, **kwargs):
    print(args)
    print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) 会输出:
    (1, 2)
    {"a": 3, "b": 4}
"""

# 当调用函数时,你可以做跟args/kwargs相反的事情!
# 用*号来扩展位置参数,用**来扩展关键字参数
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
all_the_args(*args)   # 等同于foo(1, 2, 3, 4)
all_the_args(**kwargs)   # 等同于foo(a=3, b=4)
all_the_args(*args, **kwargs)   # 等同于foo(1, 2, 3, 4, a=3, b=4)

# 通过相应地设置符号*和符号** 
# 你可以向其接收args/kwargs的函数传递args和kwargs
def pass_all_the_args(*args, **kwargs):
    all_the_args(*args, **kwargs)
    print varargs(*args)
    print keyword_args(**kwargs)

# 函数作用域                                                            
x = 5

def setX(num):
    # 局部变量x跟全局变量x不是同一个
    x = num # => 43
    print x # => 43

def setGlobalX(num):
    global x
    print x # => 5
    x = num # 全局变量x现在被设置成6
    print x # => 6

setX(43)
setGlobalX(6)

# Python有first class函数
# [译者注:关于first class function,请参照函数式编程相关书籍
# first class function:它可以让你的函数就像变量一样来使用。也就是说,你的函数可以像变量一样被创建,修改,并当成变量一样传递,返回或是在函数中嵌套函数。]
def create_adder(x):
    def adder(y):
        return x + y
    return adder

add_10 = create_adder(10)
add_10(3)   # => 13

# 还有匿名函数
(lambda x: x > 2)(3)   # => True

# 还有一些内建的高阶函数
map(add_10, [1, 2, 3])   # => [11, 12, 13]
filter(lambda x: x > 5, [3, 4, 5, 6, 7])   # => [6, 7]

# 我们可以使用列表推导式来同样达到map 和 filter的效果
[add_10(i) for i in [1, 2, 3]]  # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5]   # => [6, 7]


####################################################
## 5. 类
####################################################

# 我们从object父类继承得到子类
class Human(object):

    # 类的属性。由这个类的所有实例共享。
    species = "H. sapiens"

    # 基本的初始化函数__init__,当这个类被实例化时被调用
    # 注意前后两个下划线用来表示存在于用户控制的命名空间中的被python保留
    # 的对象或属性,你自己不能发明使用这类的名字
    def __init__(self, name):
        # 赋值一个参数给对象实例的name属性
        self.name = name

    # 一个实例方法。所有的方法均要以"self"作为第一个参数
    def say(self, msg):
        return "%s: %s" % (self.name, msg)

    # 一个类的方法被它的所有实例所共享
    # 类方法在调用时,会将类本身作为第一个函数传入。
    @classmethod
    def get_species(cls):
        return cls.species

    # 调用类的静态方法,不需要传入类或者实例的引用
    @staticmethod
    def grunt():
        return "*grunt*"


# 实例化一个类
i = Human(name="Ian")
print(i.say("hi"))     # 输出 "Ian: hi"

j = Human("Joel")
print(j.say("hello"))  # 输出 "Joel: hello"

# 调用我们的类方法
i.get_species()   # => "H. sapiens"

# 修改共享的属性
Human.species = "H. neanderthalensis"
i.get_species()   # => "H. neanderthalensis"
j.get_species()   # => "H. neanderthalensis"

# 调用静态方法
Human.grunt()   # => "*grunt*"


####################################################
## 6. 模块
####################################################

# 你可以导入模块
import math
print(math.sqrt(16))  # => 4

# 你可以从模块中导入指定函数
from math import ceil, floor
print(ceil(3.7))  # => 4.0
print(floor(3.7))   # => 3.0

# 你也可以一次性从模块中导入所有函数
# 警告: 这不是推荐的方法
from math import *

# 你可以让模块的名字变得短一些
import math as m
math.sqrt(16) == m.sqrt(16)   # => True
# 你可以测试下这两个函数其实是同一个
from math import sqrt
math.sqrt == m.sqrt == sqrt  # => True

# Python中的模块只是普通的python文件。你可以有自己的模块。 
# 你可以导入它们。模块的名字就是该文件的的名字

# 你可以找出都是由哪些函数和属性构成了一个模块
import math
dir(math)


####################################################
## 7. 高级功能
####################################################

# 生成器帮助你让代码变得"懒惰"
def double_numbers(iterable):
    for i in iterable:
        yield i + i

# 生成器在运行的时候创建值
# 它是在每一次的迭代中创建一个值,而不是一次性创建并返回所有的值
# 这意味着,在我们这个例子中,大于15的数将不会在double_numbers函数中处理.
# 注意xrange是一个生成器,不过它做的事情跟range是一样的
# 创建一个1-900000000的列表会花费很多时间和存储空间
# xrange创建一个xrange生成器,而不是像range那样一次性创建整个列表
# 如果希望使用跟python关键字冲突的变量名,我们可以在变量末尾添加一个下划线
xrange_ = xrange(1, 900000000)

# 将会把所有的数翻倍,直到result大等于30
for i in double_numbers(xrange_):
    print(i)
    if i >= 30:
        break


# 装饰器
# 在这个例子里beg包装了say
# Beg将会调用say。如果say_please为True,那么它会修改返回的消息

from functools import wraps


def beg(target_function):
    @wraps(target_function)
    def wrapper(*args, **kwargs):
        msg, say_please = target_function(*args, **kwargs)
        if say_please:
            return "{} {}".format(msg, "Please! I am poor :(")
        return msg

    return wrapper


@beg
def say(say_please=False):
    msg = "Can you buy me a beer?"
    return msg, say_please


print(say())  # Can you buy me a beer?
print(say(say_please=True))  # Can you buy me a beer? Please! I am poor :(

没读过瘾,想要阅读更多内容?

免费在线阅读 (Free Online)

实体书 (Dead Tree)

译者注

  • 更新时间:2014-12-01
  • 本人翻译的初衷是为了自身学习和记录,翻译不好的地方,还望读者见谅。
  • 这篇翻译是目前网上最新的,包括了所有新的改动,原文在 Learn X in Y Minutes: Where X = Python
  • 本人会持续关注原文的更新,并保证这里的一直是最新版。
  • 更多最新原创的译文,请关注本人的Github https://github.com/mainframer/Python-Doc-zh-CN,只翻译经典,只翻译精华。

Comments !